package com.xiaowen.projectData.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.google.common.collect.Lists;
import com.xiaowen.codeData.service.CodeDataService;
import com.xiaowen.projectData.dto.ProjectDataCodeUpdateReq;
import com.xiaowen.projectData.dto.ProjectDataQueryDTO;
import com.xiaowen.projectData.entity.ProjectData;
import com.xiaowen.projectData.mapper.ProjectDataMapper;
import com.xiaowen.projectData.service.ProjectDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaowen.projectDataCode.entity.ProjectDataCode;
import com.xiaowen.projectDataCode.service.ProjectDataCodeService;
import com.xiaowen.projectDataTitle.dto.ProjectDataTitleDTO;
import com.xiaowen.projectDataTitle.entity.ProjectDataTitle;
import com.xiaowen.projectDataTitle.mapper.ProjectDataTitleMapper;
import com.xiaowen.projectDataTitle.service.ProjectDataTitleService;
import com.xiaowen.tool.JsonUtils;
import com.xiaowen.tool.ObjUtils;
import com.xiaowen.tool.excle.ExcelExportDTO;
import com.xiaowen.tool.excle.ExcelTitle;
import com.xiaowen.tool.excle.PoiExcelUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 项目数据表 服务实现类
 * </p>
 *
 * @author yf-wenhao
 * @since 2024-09-30
 */
@Service
public class ProjectDataServiceImpl extends ServiceImpl<ProjectDataMapper, ProjectData> implements ProjectDataService {

    @Autowired
    private ProjectDataMapper projectDataMapper;

    @Autowired
    private ProjectDataCodeService projectDataCodeService;

    @Autowired
    private ProjectDataTitleMapper projectDataTitleMapper;

    @Override
    public void batchAddProjectData(List<ProjectData> projectDataList) {
        projectDataList.forEach(projectData -> {
            projectDataMapper.insert(projectData);
        });
    }

    @Override
    public void deleteProjectDataByProjectId(Integer projectId) {
        ProjectData entity = new ProjectData();
        entity.setDeleteFlag(true);

        QueryWrapper<ProjectData> queryWrapper = new QueryWrapper<>();
        ProjectData projectData = new ProjectData();
        projectData.setProjectId(projectId);
        projectData.setDeleteFlag(false);
        queryWrapper.setEntity(projectData);
        projectDataMapper.update(entity, queryWrapper);
    }

    @Override
    public IPage<Map> queryProjectDataPageByProjectId(ProjectDataQueryDTO projectDataQueryDTO) {
        IPage<Map> pageResult = new PageDTO<>();

        IPage<ProjectData> pageParam = new PageDTO<>(projectDataQueryDTO.getPage(), projectDataQueryDTO.getPageSize());
        QueryWrapper<ProjectData> queryWrapper = new QueryWrapper<>();
        ProjectData projectData = new ProjectData();
        projectData.setProjectId(projectDataQueryDTO.getProjectId());
        projectData.setDeleteFlag(false);
        queryWrapper.setEntity(projectData);
        if (ObjectUtil.isNotEmpty(projectDataQueryDTO.getIdVal())){
            queryWrapper.like("id_val", projectDataQueryDTO.getIdVal());
        }
        if (ObjectUtil.isNotEmpty(projectDataQueryDTO.getOriginalWordVal())){
            queryWrapper.like("original_word_val", projectDataQueryDTO.getOriginalWordVal());
        }
        if (ObjUtils.isNotEmpty(projectDataQueryDTO.getCodeList())){
            List<ProjectDataCode> projectDataCodeList = projectDataCodeService.queryDataCodeByCode(projectDataQueryDTO.getProjectId(), projectDataQueryDTO.getCodeList());
            if (CollectionUtils.isNotEmpty(projectDataCodeList)){
                List<Integer> projectDataIdList = projectDataCodeList.stream().map(ProjectDataCode::getProjectDataId).collect(Collectors.toList());
                queryWrapper.in("id", projectDataIdList);
            }
        }
        IPage<ProjectData> pageData = projectDataMapper.selectPage(pageParam, queryWrapper);
        Map<Integer, List<ProjectDataCode>> projectDataCodeMap = projectDataCodeService.queryProjectDataCodeMap(projectDataQueryDTO.getProjectId());
        if (ObjectUtil.isNotEmpty(pageData) && ObjectUtil.isNotEmpty(pageData.getRecords())){
            pageResult.setPages(pageData.getPages());
            pageResult.setCurrent(pageData.getCurrent());
            pageResult.setSize(pageData.getSize());
            pageResult.setTotal(pageData.getTotal());
            List<Map> records = pageData.getRecords().stream().map(v-> {
                Map result = JsonUtils.toBean(v.getDataValExt(), Map.class);
                if (ObjectUtil.isNotEmpty(projectDataCodeMap) && ObjectUtil.isNotEmpty(projectDataCodeMap.get(v.getId()))){
                    List<ProjectDataCode> codeList = projectDataCodeMap.get(v.getId());
                    result.put("codeList", codeList);
                }
                result.put("idColumn",v.getId());
                return result;
            }).collect(Collectors.toList());
            pageResult.setRecords(records);
        }
        return pageResult;
    }

    @Override
    public List<ProjectData> queryProjectDataListByProjectId(Integer projectId) {
        QueryWrapper<ProjectData> queryWrapper = new QueryWrapper<>();
        ProjectData projectData = new ProjectData();
        projectData.setProjectId(projectId);
        projectData.setDeleteFlag(false);
        queryWrapper.setEntity(projectData);
        List<ProjectData> projectDataList = projectDataMapper.selectList(queryWrapper);
        return projectDataList;
    }


    @Override
    public List<Map<String, Object>> queryProjectDataListWithCodeByProjectId(Integer projectId) {
        QueryWrapper<ProjectData> queryWrapper = new QueryWrapper<>();
        ProjectData projectData = new ProjectData();
        projectData.setProjectId(projectId);
        projectData.setDeleteFlag(false);
        queryWrapper.setEntity(projectData);
        List<ProjectData> projectDataList = projectDataMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(projectDataList)){
            QueryWrapper<ProjectDataTitle> titleQueryWrapper = new QueryWrapper<>();
            ProjectDataTitle projectDataTitle = new ProjectDataTitle();
            projectDataTitle.setProjectId(projectId);
            projectDataTitle.setDeleteFlag(false);
            titleQueryWrapper.setEntity(projectDataTitle);
            List<ProjectDataTitle> projectDataTitleList = projectDataTitleMapper.selectList(titleQueryWrapper);
            ProjectDataTitle dataTitle = projectDataTitleList.get(0);
            String idColumn = dataTitle.getIdColumn();
            String originalColumn = dataTitle.getOriginalWordColumn();
            Map<Integer, List<ProjectDataCode>> projectDataCodeMap = projectDataCodeService.queryProjectDataCodeMap(projectId);
            List<Map<String, Object>> dataList = projectDataList.stream().map(v-> {
                Map<String, Object> result = JsonUtils.toBean(v.getDataValExt(), Map.class);
                result.put(idColumn+ "（ID）",result.get(idColumn));
                result.put(originalColumn+ "（原话）",result.get(originalColumn));
                if (ObjectUtil.isNotEmpty(projectDataCodeMap) && ObjectUtil.isNotEmpty(projectDataCodeMap.get(v.getId()))){
                    List<ProjectDataCode> dataCodeList = projectDataCodeMap.get(v.getId());
                    if (CollectionUtils.isNotEmpty(dataCodeList)){
                        List<String> nameList = Lists.newArrayList();
                        List<String> codeList = Lists.newArrayList();
                        dataCodeList.forEach(projectDataCode -> {
                            nameList.add(projectDataCode.getName());
                            codeList.add(ObjUtils.toString(projectDataCode.getCode()));
                        });
                        String dataName = StringUtils.join(nameList,";");
                        String dataCode = StringUtils.join(codeList,";");
                        result.put("关联码表名称", dataName);
                        result.put("关联码表编码", dataCode);
                    }
                }
                return result;
            }).collect(Collectors.toList());
            return dataList;
        }
        return null;
    }

    @Override
    public void updateByProjectIdAndIdVal(ProjectData entity, Integer projectId, String idVal) {
        QueryWrapper<ProjectData> queryWrapper = new QueryWrapper<>();
        ProjectData projectData = new ProjectData();
        projectData.setProjectId(projectId);
        projectData.setDeleteFlag(false);
        projectData.setIdVal(idVal);
        queryWrapper.setEntity(projectData);
        projectDataMapper.update(entity,queryWrapper);
    }

    @Override
    public ProjectData queryByProjectIdAndIdVal(Integer projectId, String idVal) {
        QueryWrapper<ProjectData> queryWrapper = new QueryWrapper<>();
        ProjectData projectData = new ProjectData();
        projectData.setProjectId(projectId);
        projectData.setDeleteFlag(false);
        projectData.setIdVal(idVal);
        queryWrapper.setEntity(projectData);
        List<ProjectData> projectDataList = projectDataMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(projectDataList)){
            return projectDataList.get(0);
        }
        return null;
    }

    @Override
    @Transactional
    public Boolean updateCode(ProjectDataCodeUpdateReq updateReq) {
        if (ObjectUtil.isEmpty(updateReq) || ObjectUtil.isEmpty(updateReq.getProjectId()) || ObjectUtil.isEmpty(updateReq.getDataIdList())){
            return true;
        }
        //先删除， 在添加
        projectDataCodeService.deleteByProjectDataId(updateReq.getProjectId(), updateReq.getDataIdList());
        if (ObjectUtil.isNotEmpty(updateReq.getCodeList())){
            List<ProjectDataCode> projectDataCodeList = Lists.newArrayList();
            for (ProjectDataCode projectDataCode : updateReq.getCodeList()){
                for (Integer dataId : updateReq.getDataIdList()){
                    ProjectDataCode dataCode = new ProjectDataCode();
                    dataCode.setCode(projectDataCode.getCode());
                    dataCode.setName(projectDataCode.getName());
                    dataCode.setDeleteFlag(false);
                    dataCode.setCreateTime(new Date());
                    dataCode.setProjectId(projectDataCode.getProjectId());
                    dataCode.setProjectDataId(dataId);
                    projectDataCodeList.add(dataCode);
                }
            }
            projectDataCodeService.saveBatch(projectDataCodeList);
        }
        return true;
    }



    @Override
    public Boolean batchAddCode(ProjectDataCodeUpdateReq updateReq) {
        if (ObjectUtil.isEmpty(updateReq) || ObjectUtil.isEmpty(updateReq.getProjectId()) || ObjectUtil.isEmpty(updateReq.getDataIdList())){
            return true;
        }
        //只添加
        if (ObjectUtil.isNotEmpty(updateReq.getCodeList())){
            List<ProjectDataCode> projectDataCodeList = Lists.newArrayList();
            for (Integer dataId : updateReq.getDataIdList()){
                //查询当前数据下，是否已经包含对应的编码
                List<ProjectDataCode> projectDataCodes = projectDataCodeService.queryDataCodeByDataId(updateReq.getProjectId(), Lists.newArrayList(dataId));
                List<Integer> codeList = null;
                if (CollectionUtils.isNotEmpty(projectDataCodes)){
                    codeList = projectDataCodes.stream().map(ProjectDataCode::getCode).collect(Collectors.toList());
                }
                for (ProjectDataCode projectDataCode : updateReq.getCodeList()){
                    if (CollectionUtils.isNotEmpty(codeList) && codeList.contains(projectDataCode.getCode())){
                        continue;
                    }
                    ProjectDataCode dataCode = new ProjectDataCode();
                    dataCode.setCode(projectDataCode.getCode());
                    dataCode.setName(projectDataCode.getName());
                    dataCode.setDeleteFlag(false);
                    dataCode.setCreateTime(new Date());
                    dataCode.setProjectId(updateReq.getProjectId());
                    dataCode.setProjectDataId(dataId);
                    projectDataCodeList.add(dataCode);
                }
            }
            if (CollectionUtils.isNotEmpty(projectDataCodeList)){
                projectDataCodeService.saveBatch(projectDataCodeList);
            }
        }
        return true;
    }
}
